package com.bwton.msx.ccb.ui.setting;

import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.bwton.msx.ccb.R;
import com.bwton.msx.ccb.ui.setting.adapter.MotionRecyclerViewTouchHelperCallback;
import com.bwton.msx.ccb.ui.setting.adapter.MotionSequenceRecyclerAdapter;
import com.bwton.msx.ccb.utils.MotionUtil;
import com.bwton.msx.ccb.utils.PreferenceUtil;

import java.util.ArrayList;
import java.util.List;

public class SettingMotionsFragment extends Fragment {
    private final List<Integer> mSequence = new ArrayList<>();
    private final List<Integer> mOptionalMotions = new ArrayList<>();
    private MotionSequenceRecyclerAdapter mSelectedSequenceAdapter;
    private MotionSequenceRecyclerAdapter mOptionalSequenceAdapter;
    private RecyclerView mSelectedMotionsView;
    private RecyclerView mOptionalMotionsView;
    private View mOptionalDivider;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_motion_sequence,container,false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        this.mOptionalDivider = view.findViewById(R.id.line_optional_divider);
        view.findViewById(R.id.btn_recover_sequence).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mSequence.clear();
                mSequence.addAll(MotionUtil.getAllMotions());
                PreferenceUtil.setSequenceList(mSequence);
                mSelectedSequenceAdapter.removeAndAddSequence(
                        mSequence);
                updateOptionalMotionList();
            }
        });
        this.mSelectedMotionsView = view.findViewById(R.id.list_selected_motion_sequence);
        this.mOptionalMotionsView = view.findViewById(R.id.list_optional_motion);
        this.mSequence.clear();
        this.mSequence.addAll(PreferenceUtil.getSequenceList());
        this.mSelectedSequenceAdapter = new MotionSequenceRecyclerAdapter(getContext(),
                new MotionSequenceRecyclerAdapter.RecyclerOperationListener() {
                    @Override
                    public void onItemDeleted(int index) {
                        SettingMotionsFragment.this.onSequenceItemDeleted(index);
                    }

                    @Override
                    public void onDataReorder(List<Integer> data) {
                        SettingMotionsFragment.this.onSequenceItemUpdate(data);
                    }
                });

        this.mSelectedSequenceAdapter.removeAndAddSequence(this.mSequence);
        this.mSelectedSequenceAdapter.setLastOneEnable(false);
        this.mSelectedMotionsView.setLayoutManager(new LinearLayoutManager(getContext()));
        this.mSelectedMotionsView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
        this.mSelectedMotionsView.setAdapter(this.mSelectedSequenceAdapter);
        ItemTouchHelper.Callback callback = new MotionRecyclerViewTouchHelperCallback(this.mSelectedSequenceAdapter);
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        touchHelper.attachToRecyclerView(this.mSelectedMotionsView);
        this.mOptionalSequenceAdapter = new MotionSequenceRecyclerAdapter(getContext(),
                new MotionSequenceRecyclerAdapter.RecyclerOperationListener() {
                    @Override
                    public void onItemDeleted(int index) {
                        onOptionalSequenceSelected(index);
                    }

                    @Override
                    public void onDataReorder(List<Integer> data) {
                        // Do nothing.
                    }
                });

        this.mOptionalSequenceAdapter.setSuffixImageEnable(false);
        this.mOptionalSequenceAdapter.setLastOneImageResource(R.drawable.ic_add_motion);
        this.mOptionalSequenceAdapter.setPrefixImageResource(R.drawable.ic_add_motion);
        this.mOptionalMotionsView.setLayoutManager(new LinearLayoutManager(getContext()));
        this.mOptionalMotionsView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
        this.mOptionalMotionsView.setAdapter(this.mOptionalSequenceAdapter);
        updateOptionalMotionList();
    }


    /**
     * Delete motion from current sequence.
     *
     * @param sequenceIndex Motion index in current sequence.
     */
    public void onSequenceItemDeleted(final int sequenceIndex) {
        this.mSequence.remove(sequenceIndex);
        PreferenceUtil.setSequenceList(this.mSequence);
        this.mSelectedSequenceAdapter.removeAndAddSequence(this.mSequence);

        updateOptionalMotionList();
    }

    /**
     * Update current sequence order.
     *
     * @param sequence New sequence ordered.
     */
    public void onSequenceItemUpdate(final List<Integer> sequence) {
        this.mSequence.clear();
        this.mSequence.addAll(sequence);
        PreferenceUtil.setSequenceList(this.mSequence);
    }

    /**
     * Select a valid motion of optional motion sequence.
     *
     * @param optionalSequenceIndex Index of motion selected in optional sequence.
     */
    public void onOptionalSequenceSelected(final int optionalSequenceIndex) {
        this.mSequence.add(this.mOptionalMotions.get(optionalSequenceIndex));
        PreferenceUtil.setSequenceList(this.mSequence);
        this.mSelectedSequenceAdapter.addMotion(this.mOptionalMotions.get(optionalSequenceIndex));

        updateOptionalMotionList();
    }

    private List<Integer> getOptionalMotions() {
        List<Integer> motions = MotionUtil.getAllMotions();
        motions.removeAll(this.mSequence);
        return motions;
    }

    private void updateOptionalMotionList() {
        this.mOptionalMotions.clear();
        this.mOptionalMotions.addAll(getOptionalMotions());
        if (this.mOptionalMotions.isEmpty()) {
            this.mOptionalDivider.setVisibility(View.VISIBLE);
            this.mOptionalMotionsView.setVisibility(View.GONE);
            this.mOptionalSequenceAdapter.removeAndAddSequence(this.mOptionalMotions);
        } else {
            this.mOptionalDivider.setVisibility(View.GONE);
            this.mOptionalMotionsView.setVisibility(View.VISIBLE);
            this.mOptionalSequenceAdapter.removeAndAddSequence(this.mOptionalMotions);
        }
    }
}
